/*
 * abstractLibrary.java
 *
 * Copyright(c) 2010
 * Michael Kroez
 * kroez@studiorutton.de
 *
 * All rights reserved.
 *
 * $Id$
 * 
 */

package de.studiorutton.gerengdic.update;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.util.Log;
import de.studiorutton.access.FileAccess;
import de.studiorutton.access.FileAccessException;
import de.studiorutton.access.FileLocation;
import de.studiorutton.access.FileProperties;
import de.studiorutton.access.InAndOutputStream;
import de.studiorutton.access.IProgressListener;
import de.studiorutton.access.Result;
import de.studiorutton.access.Result.ErrorCode;
import de.studiorutton.access.WebAccess;
import de.studiorutton.access.WebspaceException;

public class UpdateFile {
	private final static String TAG = "learningwords";
	
	protected FileLocation fileLocation;
	protected InAndOutputStream inAndOut;

	public UpdateFile( FileLocation fileLocation ) {
		this.fileLocation = fileLocation;
	}

	public void setFileLocation(FileLocation fileLocation) {
		this.fileLocation = fileLocation;
	}

	public FileLocation getFileLocation() {
		return fileLocation;
	}

	public Result updateFile(boolean checkOnlyForNewer, IProgressListener pl) {

//		Log.d( TAG, "Opening webaccess filelocation . " + fileLocation.createFileURI() );
		final WebAccess wa = new WebAccess(fileLocation);
//		Log.d( TAG, "Opened webaccess filelocation . " + fileLocation.createFileURI() );
		FileProperties fpRemote;
		try {
			fpRemote = wa.getFileProperties();
		} catch (WebspaceException e) {
			return new Result( Result.ERROR_REMOTE_ERROR, ErrorCode.ERROR_CANNOT_REACH_REMOTE_SERVER, e.getLocalizedMessage());
		}
		FileAccess fa = new FileAccess(fileLocation);
		FileProperties fpLocal;
		try {
			fpLocal = fa.getFileProperties();
		} catch (FileAccessException e1) {
			return new Result( Result.ERROR_LOCAL_ERROR, ErrorCode.ERROR_CANNOT_GET_EXTERNAL_STORAGE );
		}

		if (checkOnlyForNewer) {
			boolean remoteIsNewer = false;
			if (fpLocal == null)
				remoteIsNewer = true;
			else
				remoteIsNewer = fpRemote.isNewerThan(fpLocal);

			if (remoteIsNewer) {
				return new Result( Result.STATUS_REMOTE_NEWER, ErrorCode.STATUS_REMOTE_FILE_NEWER );
			}
			else {
				return new Result( Result.STATUS_REMOTE_NOT_NEWER, ErrorCode.STATUS_REMOTE_FILE_NOT_NEWER );
			}
		}

		InputStream in;
		try {
			in = wa.getInputStream(pl);
		} catch (WebspaceException e) {
			return new Result( Result.ERROR_REMOTE_ERROR, ErrorCode.ERROR_DURING_READING_AND_WRITING, e.getLocalizedMessage());
		}
		OutputStream out;
		try {
			out = fa.getOutputStream( true );
		} catch (FileAccessException e) {
			return new Result( Result.ERROR_LOCAL_ERROR, ErrorCode.ERROR_DURING_READING_AND_WRITING, e.getLocalizedMessage());
		}
		inAndOut = new InAndOutputStream(in, out);
		
		int result;
		try {
			result = inAndOut.readAndWrite();
			inAndOut.close();
		} catch (IOException e) {
			return new Result( Result.ERROR_READING_WRITING, ErrorCode.ERROR_DURING_READING_AND_WRITING, e.getLocalizedMessage() );
		}
		
		if ( result == -2 )
			return new Result( Result.OKAY, ErrorCode.ERROR_EVERYTHING_OK_AND_DONE );
		else if ( result == -1 )
			return new Result( Result.ERROR_READING_WRITING, ErrorCode.ERROR_DURING_READING_AND_WRITING );
		
		try {
			if (!fa.moveFromTmpToRealPath())
				return new Result( Result.ERROR_READING_WRITING, ErrorCode.ERROR_DURING_READING_AND_WRITING );
		} catch (FileAccessException e) {
			return new Result( Result.ERROR_READING_WRITING, ErrorCode.ERROR_DURING_READING_AND_WRITING, e.getLocalizedMessage() );
		}
		
		return new Result( Result.OKAY, ErrorCode.ERROR_EVERYTHING_OK_AND_DONE );
	}
	
	public void cancelUpdateFile() {
		if ( inAndOut != null )
			inAndOut.setCancelReadAndWrite( true );
	}

}
